<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>es6语法</title>
</head>

<body>
    <!-- <div class="scroll-x tabs">
        <div class="tab">
            <p>标签1</p>
            <div class="indicator"></div>
        </div>
        <div class="tab">
            <p>标签1</p>
            <div class="indicator"></div>
        </div>
        <div class="tab">
            <p>标签1</p>
            <div class="indicator"></div>
        </div>
        <div class="tab">
            <p>标签1</p>
            <div class="indicator"></div>
        </div>
    </div> -->

</body>
<script>
    //let声明变量：
    // 1.变量不可重复声明
    // let star = 'smx'
    // let star = 'cmx'
    // 报错
    // 2.块级作用域
    // {
    //     let name = 'cmx'
    // }
    // 在大括号内的都属于作用域内
    // 3.不存在变量提升
    // 4.不影响作用域链


    // const声明常量：
    // const SCHOOL = ‘学校’;一般习惯把常量全用大写字母
    // 1.一定要赋初始值
    // 2.一般常量使用大写（潜规则）
    // 3.常量值不能修改
    // 4.块级作用域
    // 5.对数组和对象的元素修改，不算对常量的修改，不会报错

    //数组的解构
    // const F4 = ["小沈阳", "刘能", "赵四", "宋小宝"];
    // let [xiao, liu, zhao, song] = F4;
    // console.log(xiao);
    // console.log(liu);
    // console.log(zhao);
    // console.log(song);

    //对象的解构
    //   const zhaob = {
    //     name: "赵本山",
    //     age: "no",
    //     xiaopin: function () {
    //       console.log("我会小品");
    //     },
    //   };
    //   let { name, age, xiaopin } = zhaob;
    //   console.log(xiaopin);
    //可以寻找同名属性进行赋值
    //   let { name } = zhaob;
    //     console.log(name);

    // ES6引入了新的声明字符串的方式 ``(反引号)
    // let str = `我也是一个字符串哦`

    //     let str = `
    //     <ul>
    //         <li>a</li>
    //         <li>b</li>
    //         <li>c</li>
    //     </ul>
    // `
    //     console.log(str);

    // ES6中允许直接在大括号里直接写入变量和函数，作为对象的属性和方法、
    // let name1 = "悦悦";
    //     let job = `${name1}是嫦娥的兔兔`;
    //     console.log(job);

    //     let school = {
    //       name1,
    //       job,
    //       fun() {
    //         console.log(1);
    //       },
    //     };
    //当变量作为对象的属性时，不用再写成name1：name1，方法fun：fuction(){}也可以直接简写成fun(){}


    //${}是变量拼接的固定格式

    // 箭头函数
    // 以前的函数为：let fun = function(a,b){}
    // 箭头函数则改为：let fun = (a,b)=>{}

    // 1.this是静态的，this始终指向函数声明时所在作用域下的this的值
    // 2.不能作为构造函数实例化对象
    // 3.不能使用arguments变量
    // 4.箭头函数的简写
    // （1）当形参只有一个时候，可以省略小括号
    // let fun = a=>{}

    // (2)当大括号内只有一句话的时候，大括号可以省略,而且语句执行结果就是函数的返回值
    // let fun = a=> a+b

    // (3)箭头函数适合与this无关的回调，如定时器，数组方法的回调。不适合与this有关的回调，如事件回调，对象方法

    // 形参初始值，是具有默认值的参数，这种参数一般都在最后（潜规则）并且可以进行解构赋值
    // function connect({ a, b, c = 101 }) {
    //   console.log(a);
    //   console.log(b);
    //   console.log(c);
    // }
    // connect({
    //   a: 1,
    //   b: 2,
    // });

    // ES6引入了rest参数，用来获取函数实参，形式是：…args，用来代替arguments,并且rest参数必须放到最后，当多个实参时候，…args会形成数组。

    // function fun(a, b, ...args) {
    //   console.log(a);
    //   console.log(b);
    //   console.log(args);
    // }
    // fun(1, 2, 3, 4, 5, 6);

    // 扩展运算符：…，能将数组转化为逗号分隔的参数序列

    // let arr = [1, 2, 3, 4, 5, 6];
    //     function fun() {
    //       console.log(arguments);
    //     }
    //     fun(arr);
    //这是没用扩展运算符的
    // let arr = [1, 2, 3, 4, 5, 6];
    // function fun() {
    //   console.log(arguments);
    // }
    // fun(...arr);

    // 扩展运算符的应用合并数组
    // 数组克隆
    // 伪数组转为真数组

    //     let arr1 = ["奇拉", "少卡"];
    // let arr2 = ["舒克都", "放假"];
    // let arr = [...arr1, ...arr2];
    // console.log(arr);
    // let arr3 = [...arr2];
    // console.log(arr3);

    // let divs = document.querySelectorAll("div");
    // let divarr = [...divs];
    // console.log(divarr);

    // symbol基本使用：ES6引入的一种新的原始数据类型，表示独一无二的值，他的特点
    // 1.symbol的值是唯一的，用来解决命名冲突问题

    // 2.symbol不能与其他值进行运算

    // 3.symbol定义的对象属性不能用for…in遍历循环，单可以使用Reflect.ownKeys来获取所有对象的键名

    //创建symbol
    // let s = Symbol();
    // console.log(s);
    // let s2 = Symbol("速度快");
    // console.log(s2);
    // let s3 = Symbol("速度快");
    // console.log(s2 === s3);
    // //symbol.for创建
    // let s4 = Symbol.for("速度快");
    // console.log(s4);
    // let s5 = Symbol.for("速度快");
    // console.log(s5);
    // console.log(s4 === s5);
    // symbol的使用：向对象中添加symbol类型的方法

    // 迭代器：是一种接口，为各种不同的数据提供统一的访问机制。任何数据结构只要部署了iterator接口，就可以完成遍历操作
    // 1.ES6创造了一种新的遍历命令：for…of循环，iterator接口主要提供for…of消费

    // 2.原生具备iterator接口的数据(可用for…of遍历)

    // Array/Arguments/Set/Map/String/TypeArray/NodeList


    //     3.工作原理

    // a) 创建一个指针对象，指向当前数据的起始位置

    // b) 第一次调用对象的next方法，指针自动指向数据结构的第一个成员

    // c) 接下来不断调用next方法，指针一直往后移动，直到指向最后一个成员

    // let Uname = ["搜到", "的撒", "的风格", "范德萨", "公司发", "告诉对方"];
    // for (let a of Uname) {
    //  console.log(a);
    // }
    // let iterator = Uname[Symbol.iterator]();
    // console.log(iterator.next());
    // console.log(iterator.next());
    // console.log(iterator.next());
    // console.log(iterator.next());
    // console.log(iterator.next());
    // console.log(iterator.next());
    // console.log(iterator.next());
    //false表示数组成员没遍历结束，true表示结束。

    // 生成器：是es6提供的一种异步编程解决方案，是一个特殊的函数

    // function* fun2() {
    //     yield '一直没有耳朵';
    //     yield '一直没有尾巴';
    //     yield '真奇怪';
    // }
    // let tor = fun2()
    // console.log(tor.next())
    // console.log(tor.next())
    // console.log(tor.next())
    // console.log(tor.next())

    // 生成器的函数参数：next()方法在调用的时候可以传递实参的，第二个next传递的参数将作为第一个yield整体的返回结果，
    // 后面的依次，第三个next传递的参数将作为第二个yield的整体返回结果

    // function* fun2(arg) {
    //     console.log(arg)
    //     let A = yield '一直没有耳朵';
    //     console.log(A)
    //     let B = yield '一直没有尾巴';
    //     console.log(B)
    //     let C = yield '真奇怪';
    //     console.log(C)
    // }
    // let tor = fun2('aaa')
    // console.log(tor.next())
    // console.log(tor.next('bbb'))
    // console.log(tor.next('ccc'))
    // console.log(tor.next('ddd'))

    // 生成器的实例：模拟获取 用户数据 订单数据 商品数据，每隔一秒显示。

    function getUser() {
        setTimeout(() => {
            let data = '用户数据'
            //调用next方法，并且把数据传入
            iterator2.next(data)
        }, 1000)
    }
    function getOrder() {
        setTimeout(() => {
            let data = '订单数据'
            iterator2.next(data)
        }, 1000)
    }
    function getFGoods() {
        setTimeout(() => {
            let data = '商品数据'
            iterator2.next(data)
        }, 1000)
    }
    function* fun3() {
        let user = yield getUser();
        console.log(user)
        let Order = yield getOrder();
        console.log(Order)
        let Goods = yield getFGoods();
        console.log(Goods)
    }
    let iterator2 = fun3()
    iterator2.next()





</script>

</html>